1   // Copyright 2006, 2009 The Apache Software Foundation
2   //
3   // Licensed under the Apache License, Version 2.0 (the "License");
4   // you may not use this file except in compliance with the License.
5   // You may obtain a copy of the License at
6   //
7   //     http://www.apache.org/licenses/LICENSE-2.0
8   //
9   // Unless required by applicable law or agreed to in writing, software
10  // distributed under the License is distributed on an "AS IS" BASIS,
11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  // See the License for the specific language governing permissions and
13  // limitations under the License.
14  
15  package org.apache.tapestry5.ioc.internal.util;
16  
17  import java.util.ArrayList;
18  import java.util.List;
19  import org.apache.tapestry5.ioc.Invokable;
20  
21  import java.util.concurrent.TimeUnit;
22  
23  public class ConcurrentTarget
24  {
25      private final ConcurrentBarrier barrier = new ConcurrentBarrier();
26  
27      private int counter;
28  
29      // Used to check if read locks accumulate when a read lock method calls another read lock method
30      public int readCounter()
31      {
32          return barrier.withRead(new Invokable<Integer>()
33          {
34              @Override
35              public Integer invoke()
36              {
37                  return getCounter();
38              }
39          });
40      }
41  
42      public int getCounter()
43      {
44          return barrier.withRead(new Invokable<Integer>()
45          {
46              @Override
47              public Integer invoke()
48              {
49                  return counter;
50              }
51          });
52      }
53  
54      public void incrementCounter()
55      {
56          barrier.withWrite(new Runnable()
57          {
58              @Override
59              public void run()
60              {
61                  counter++;
62              }
63          });
64      }
65  
66      public void setCounter(final int counter)
67      {
68          barrier.withWrite(new Runnable()
69          {
70              @Override
71              public void run()
72              {
73                  ConcurrentTarget.this.counter = counter;
74              }
75          });
76      }
77  
78      public void incrementIfNonNegative()
79      {
80          barrier.withRead(new Runnable()
81          {
82              @Override
83              public void run()
84              {
85                  if (counter >= 0)
86                      incrementCounter();
87              }
88          });
89      }
90  
91      public void incrementViaRunnable()
92      {
93          barrier.withRead(new Runnable()
94          {
95              @Override
96              public void run()
97              {
98                  Runnable r = new Runnable()
99                  {
100                     @Override
101                     public void run()
102                     {
103                         incrementCounter();
104                     }
105                 };
106 
107                 r.run();
108             }
109         });
110     }
111 
112     public void incrementCounterHard()
113     {
114         barrier.withWrite(new Runnable()
115         {
116             @Override
117             public void run()
118             {
119                 counter = getCounter() + 1;
120             }
121         });
122     }
123 
124     public boolean tryIncrementCounter()
125     {
126         return barrier.tryWithWrite(new Runnable()
127         {
128             @Override
129             public void run()
130             {
131                 counter++;
132             }
133         }, 20, TimeUnit.MILLISECONDS);
134     }
135 
136     public boolean tryIncrementCounterHard()
137     {
138         return barrier.tryWithWrite(new Runnable()
139         {
140             @Override
141             public void run()
142             {
143                 counter = getCounter() + 1;
144             }
145         }, 20, TimeUnit.MILLISECONDS);
146     }
147 
148     public boolean tryIncrementIfNonNegative()
149     {
150         final List<Boolean> result = new ArrayList<Boolean>();
151         barrier.withRead(new Runnable()
152         {
153             @Override
154             public void run()
155             {
156                 if (counter >= 0)
157                     result.add(tryIncrementCounter());
158             }
159         });
160         return result.get(0);
161     }
162 
163 
164     public void withRead(Runnable runnable)
165     {
166         barrier.withRead(runnable);
167     }
168 }